/* 
 * File:   Real.cpp
 * Author: Gab'z
 * 
 * Created on 29 mai 2012, 12:26
 */

#include "Real.h"
#include "Integer.h"
#include "Rationnal.h"
#include "../../../exception/ArithmeticException.h"
#include <sstream> 
#include <cmath>

namespace calculator {

    Real::Real(double x) : SimpleNumber(), _x(x) {
    }

    Real::Real(const Real& real) : SimpleNumber(), _x(real._x) {
    }

    Real::Real(const Integer& integer) : _x((double) integer._x) {
    }

    Real::Real(const Rationnal& rationnal) : _x((double) rationnal._num / (double) rationnal._denom) {
    }

    Real::~Real() {
    }

    Real* Real::clone() const {
        return new Real(_x);
    }

    std::string Real::toString() const {
        std::ostringstream oss;
        oss << _x;
        return oss.str();
    }

    double Real::value() const {
        return _x;
    }

    Real& Real::operator=(const Real& real) {
        if (this == &real) return *this;
        _x = real._x;
        return *this;
    }

    Real& Real::operator+=(const Real& real) {
        _x += real._x;
        return *this;
    }

    Real& Real::operator-=(const Real& real) {
        _x -= real._x;
        return *this;
    }

    Real& Real::operator*=(const Real& real) {
        _x *= real._x;
        return *this;
    }

    Real& Real::operator/=(const Real& real) {
        if (real._x == 0) throw ArithmeticException("Real divided by 0");
        _x /= real._x;
        return *this;
    }

    Real& Real::pow(const SimpleNumber& sn) {
        _x = std::exp(sn.value() * std::log(_x));
        return *this;
    }

    Real operator+(const Real& r1, const Real& r2) {
        Real real(r1);
        real += r2;
        return real;
    }

    Real operator-(const Real& r1, const Real& r2) {
        Real real(r1);
        real -= r2;
        return real;
    }

    Real operator*(const Real& r1, const Real& r2) {
        Real real(r1);
        real *= r2;
        return real;
    }

    Real operator/(const Real& r1, const Real& r2) {
        Real real(r1);
        real /= r2;
        return real;
    }

    Real pow(const Real& r1, const SimpleNumber& sn) {
        Real real(r1);
        real.pow(sn);
        return real;
    }
}